#ifndef _CPU_CONSTS_H_
#define _CPU_CONSTS_H_
/*
 *  cpu_consts.c
 *  Archetecture dependent settings and structs
 *
 *              CPU Monitor 
 *
 *    Spring Semester.  044800.    Technion.
 *   Copyright (C) 2006  Evgeny Shulman  and Elizabeth Shtrom 
 */
 

#include <asm/segment.h> 
//#define GDT_ENTRIES 32
//#define GDT_SIZE (GDT_ENTRIES * 8)
//
//#define IDT_ENTRIES 256
/* Maximum number of LDT entries supported. */


#define  MAXnrCPUs 2

/*take from ldt.h */
#define LDT_ENTRIES     5  /* The are only 5 entries in the LDT in our system */
#define LDT_ENTRY_SIZE  8

 /* The size of each LDT entry. */
#define LDT_SIZE LDT_ENTRIES*LDT_ENTRY_SIZE 

#define GATE_SIZE  8
#define IDT_SIZE IDT_ENTRIES*GATE_SIZE 

#define PGD_TABLE_ENTRIES 1024
#define PT_TABLE_ENTRIES  1024


#define IO_BITMAP_BITS  65536
#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))

#define CM_IDT_MAX 			0x100


#define CM_SYS_DESC_TYPE_TSS		  0x01
#define CM_SYS_DESC_TYPE_LDT		  0x02
#define CM_SYS_DESC_TYPE_TSSB		  0x03
#define CM_SYS_DESC_TYPE_CALLG		0x04
#define CM_SYS_DESC_TYPE_TASKG		0x05
#define CM_SYS_DESC_TYPE_INTG		  0x06
#define CM_SYS_DESC_TYPE_TRAPG		0x07

#define CM_SYS_DESC_TYPE_TSS32 	  0x09
#define CM_SYS_DESC_TYPE_TSS32B	  0x0b
#define CM_SYS_DESC_TYPE_CALLG32	0x0c
#define CM_SYS_DESC_TYPE_INTG32	  0x0e
#define CM_SYS_DESC_TYPE_TRAPG32	0x0f

#define CM_SYS_DESC_OFFSET(d)  ((unsigned long)(d->offset_h << 16 | d->offset))
#define CM_SYS_DESC_CALLG_COUNT(d) ((unsigned int)(d->res & 0x0F))

#define CM_SEG_DESC_TYPE_CODE		0x08
#define CM_SEG_DESC_TYPE_CODE_R	0x02
#define CM_SEG_DESC_TYPE_DATA_W	0x02
#define CM_SEG_DESC_TYPE_CODE_C	0x04  /* conforming */
#define CM_SEG_DESC_TYPE_DATA_D	0x04  /* expand-down */
#define CM_SEG_DESC_TYPE_A		  0x01	/* accessed */

#define CM_SEG_DESC_BASE(d) ((unsigned long)(d->base_h2 << 24 | d->base_h1 << 16 | d->base))
#define _LIMIT(d) ((unsigned long)(d->limit_h << 16 | d->limit))
#define CM_SEG_DESC_LIMIT(d) (d->g ? ((_LIMIT(d)+1) << 12) -1 : _LIMIT(d))

   

#define DISP_PAGE_SHIFT	12
#define DISP_AVAIL_SHIFT	9
#define DISP_PAGE_PRESENT	0x001
#define DISP_PAGE_RW	0x002
#define DISP_PAGE_USER	0x004
#define DISP_PAGE_AVAIL 0xe00
#define DISP_PAGE_PWT	0x008
#define DISP_PAGE_PCD	0x010
#define DISP_PAGE_ACCESSED	0x020
#define DISP_PAGE_PSE	0x080	    /* 4 MB (or 2MB) page, Pentium+, if present.. */
#define DISP_PAGE_GLOBAL	0x100	/* Global TLB entry PPro+ */
#define DISP_PAGE_DIRTY	0x040
#define DISP_PAGE_PROTNONE	0x080	/* if the user mapped it with PROT_NONE;
																		 pte_present gives true */

typedef struct { unsigned long pte_low; } disp_pte_t;
typedef struct { unsigned long pgd; } disp_pgd_t;
#define disp_pte_val(x)	((x).pte_low)


typedef struct { unsigned long val; } disp_swp_entry_t;

#define DISP__LARGE_PTE (DISP_PAGE_PRESENT)
#define disp_pte_none(x)		(!(x).pte_low)
#define disp_pte_present(x)	((x).pte_low & (DISP_PAGE_PRESENT | DISP_PAGE_PROTNONE))
#define disp__pte_to_swp_entry(pte)		((disp_swp_entry_t) { (pte).pte_low })
#define disp__swp_type(x)			(((x).val >> 1) & 0x1f)
#define disp__swp_offset(x)			((x).val >> 8)

#define disp_pgd_val(x)	((x).pgd)
#define disp_pgd_none(x) (!disp_pgd_val(x))



/* i386 + x86   -> Pay attention on "unsigned long" */
struct Xgt_desc_struct {
	unsigned short size;
	unsigned long  address __attribute__((packed));
  unsigned short pad;
} __attribute__ ((packed));

typedef struct tr_ldtr_s {
	unsigned short SegLimit;
	unsigned long  Base;
	unsigned short SegSel;
} tr_ldtr_s ;	

typedef struct _cm_desc {
	unsigned short limit;
	unsigned short base;
	unsigned char base_h1;
	unsigned char type:4;
	unsigned char seg:1;
	unsigned char dpl:2;
	unsigned char present:1;
	unsigned char limit_h:4;
	unsigned char avl:2;
	unsigned char db:1;
	unsigned char g:1; /* granularity */
	unsigned char base_h2;
} __attribute__ ((packed)) cm_desc_t;

typedef struct _cm_gate_desc {
	unsigned short offset;
	unsigned short sel;
	unsigned char res;
	unsigned char type:4;
	unsigned char seg:1;
	unsigned char dpl:2;
	unsigned char present:1;
	unsigned short offset_h;
}__attribute__ ((packed)) cm_gate_desc_t;

typedef struct _cm_tss_struct {
        unsigned short  back_link,__blh;
        unsigned long   esp0;
        unsigned short  ss0,__ss0h;
        unsigned long   esp1;
        unsigned short  ss1,__ss1h;     /* ss1 is used to cache MSR_IA32_SYSENTER_CS */
        unsigned long   esp2;
        unsigned short  ss2,__ss2h;
        unsigned long   __cr3;
        unsigned long   eip;
        unsigned long   eflags;
        unsigned long   eax,ecx,edx,ebx;
        unsigned long   esp;
        unsigned long   ebp;
        unsigned long   esi;
        unsigned long   edi;
        unsigned short  es, __esh;
        unsigned short  cs, __csh;
        unsigned short  ss, __ssh;
        unsigned short  ds, __dsh;
        unsigned short  fs, __fsh;
        unsigned short  gs, __gsh;
        unsigned short  ldt, __ldth;
        unsigned short  trace, io_bitmap_base;
        /*
         * The extra 1 is there because the CPU will access an
         * additional byte beyond the end of the IO permission
         * bitmap. The extra byte must be all 1 bits, and must
         * be within the limit.
         */
} __attribute__((packed)) cm_tss_struct;


#define TSS_SIZE sizeof ( cm_tss_struct ) 

#define USER_ENTRIES 128
#define USER_SIZE(num) num*sizeof(unsigned long)  


typedef struct pgd_read_struct {
unsigned long* pgd_table;
int            index ;
} pgd_s , * pgd_p;

typedef struct pgd_indirect {
		unsigned long    *pgd_table;
}pgd_indirect;

typedef struct pt_read_struct {
unsigned long  pde;
unsigned long* pt_table;
int            index ;
} pt_s , * pt_p;

typedef struct regs_struct {
	/* i386 -32 bit   x64 - 64 bit ( 32 msb reserved)*/
 
  /* code registers :            */
   unsigned long cr0,  cr2, cr3,cr4;   
  
  /* debug registers :*/
  unsigned long dr0, dr1, dr2, dr3, dr4, dr5, dr6, dr7;

  /* segment registers :*/
  unsigned short cs , es , ss , ds , fs , gs ;
  
  struct Xgt_desc_struct gdtr; 
  struct Xgt_desc_struct idtr;
  tr_ldtr_s ldtr , tr;

} regs_s , * regs_p ;

typedef struct cpuid_struct {
	unsigned long eax,ebx,ecx,edx;
	unsigned long op;   /*code for cpuid instruction */
}__attribute__ ((packed)) cpuid_s;


typedef struct cpuid_data_struct {
	unsigned int number;
	unsigned int vendor;
	unsigned int family;
	unsigned int model;
	unsigned int stepping;
	unsigned int type;
	unsigned int brand;
	unsigned int maxi, maxei;
	char name[80];
}cpuid_data_s;



typedef struct im_irq_stat 
{
	unsigned int irqs[IDT_ENTRIES];
}im_irq_stat_s;



#endif


